<?php

// +----------------------------------------------------------------------
// | 行为事件
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 微尘 <yicmf@qq.com>
// +----------------------------------------------------------------------

namespace app\event\ucenter;

use app\model\ucenter\AuthGroup as AuthGroupModel;
use app\model\ucenter\AuthGroupAccess;
use app\model\ucenter\AuthGroupApply;
use app\model\ucenter\User as UserModel;
use app\event\ucenter\User as UserEvent;
use think\facade\Config;
use think\facade\Db;
use think\Exception;
use yicmf\tools\Auth;

class AuthGroup
{

    /**
     * 开通vip
     * /**
     * @param $user
     * @param $model
     * @return array
     */
    public function groupApply($param, $user)
    {
        try {
            if (!$user) {
                throw new Exception('会员不存在');
            }
            $group = AuthGroupModel::where('status', 1)->where('is_apply', 1)->find();

            if (!$group) {
                throw new Exception('用户组不存在');
            }

            // 是否有正在审核

            if (AuthGroupApply::where('status', 1)->where('auth_group_id', $group['id'])->find()) {
                throw new Exception('有正在等待审核');
            }

            Db::startTrans();
            $log = [];
            $log['auth_group_id'] = $group['id'];
            $log['user_id'] = $user['id'];
            $log = AuthGroupApply::create($log);

            Db::commit();
            $data['code'] = 0;
            $data['message'] = '申请已经提交';
            $data['data'] = $log;
        } catch (Exception $e) {
            Db::rollback();
            $data['code'] = 1;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 检测权限.
     * @param                $rule     string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
     * @param UserModel $user
     * @param array $type
     * @param string mode 执行check的模式
     * @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
     * @return bool
     * @return bool
     * @author  : 微尘 <yicmf@qq.com>
     */
    public static function checkRule($rule, $user, $type = '1,2', $mode = 'url', $relation = 'or')
    {

        if (UserEvent::isAdministrator($user) || !Config::get('auth.auth_on')) {
            return true;
        }
//			$allow = array_map('strtolower', Config::get('auth.allow_visit'));
//			$deny = array_map('strtolower', Config::get('auth.deny_visit'));
        $allow = Config::get('auth.allow_visit');
        $deny = Config::get('auth.deny_visit');
        if (self::_checkInRule($rule, $deny)) {
            return false; //非超管禁止访问deny中的方法
        }
        if (self::_checkInRule($rule, $allow)) {
            return true;
        }
        $public_visit = Config::get('auth.public_visit');
        if (self::_checkInRule($rule, $public_visit)) {
            return true;
        }
        //next:需要检测节点权限
        static $Auth = null;
        if (!$Auth) {
            $Auth = new Auth();
        }
        return $Auth->check($rule, $user['id'], $type, $mode, $relation);
    }

    /**
     * @param $rule
     * @param $rules
     * @return bool
     */
    protected static function _checkInRule($rule, $rules): bool
    {
        if (empty($rules)) {
            return false;
        }
        sort($rules);
        $rule_array = [];
        foreach ($rules as $key => $item) {
            if (is_string($item)) {
                $temp = explode('/', $item);
                if (isset($temp[1])) {
                    $rule_array[$temp[0]][$temp[1]][] = isset($temp[2]) ? $temp[2] : '*';
                } else {
                    $rule_array[$temp[0]][] = '*';
                }
            } else {
                if (isset($rule_array[array_key_first($item)])) {
                    $rule_array[array_key_first($item)] = array_merge($item[array_key_first($item)], $rule_array[array_key_first($item)]);
                } else {
                    $rule_array = array_merge($rule_array, $item);
                }
            }
        }
        $rule = explode('/', $rule);
        if (in_array($rule[0], array_keys($rule_array))) {
            $rule2 = $rule_array[$rule[0]];
            if (in_array($rule[1], array_keys($rule2)) || in_array('*', array_keys($rule2))) {
                if (in_array('*', array_keys($rule2))) {
                    return true;
                } else {
                    $rule3 = $rule_array[$rule[0]][$rule[1]];
                    if (in_array($rule[2], $rule3) || in_array('*', array_keys($rule3))) {
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static function getMenuIds($user)
    {
        $arr = [];
        foreach ($user->roles()->select() as $index => $role) {
            $arr = array_merge($arr, $role['menu_rules']);
        }
        return $arr;
    }

    /**
     * 用户权限
     *
     * @param      $param
     * @param null $user
     * @return mixed
     * @throws Exception
     */
    public function access($param, $user = null)
    {
        if (empty($param['group_id'])) {
            throw new Exception('权限组不存在');
        }
        $group = AuthGroupModel::get($param['group_id']);
        if (!$group) {
            throw new Exception('权限不存在');
        }
        // 移除权限
        AuthGroupAccess::where('auth_group_id', $group['id'])->where('user_id', $param['user_id'])->delete();
        if ('add' == $param['type']) {
            // 增加
            $insert = [];
            $insert['auth_group_id'] = $group['id'];
            $insert['user_id'] = $param['user_id'];
            AuthGroupAccess::create($insert);
        }
        $data['data'] = $group;
        $data['code'] = 0;
        return $data;
    }

    /**
     * 变更权限
     * @param           $param
     * @param UserModel $user
     * @return mixed
     */
    public function rule($param, $user)
    {
        try {
            $group = AuthGroupModel::where('id', $param['id'])->find();
            if (!$group) {
                throw new Exception('权限不存在');
            }
            // 判断修改等级
            if (!UserEvent::isAdministrator($user)) {
                throw new Exception('权限等级不足');
            }
            // 权限节点
            if (isset($param['type']) && $param['type'] == 'base') {
                $nodes = json_decode($param['nodes'], true);
                $rules = [];
                foreach ($nodes as $node) {
                    foreach ($node['children'] as $children) {
                        if (isset($children['children'])) {
                            foreach ($children['children'] as $child) {
                                $rules[] = $child['id'];
                            }
                        } else {
                            $rules[] = $children['id'];
                        }
                    }
                }
                sort($rules);
                $group['rules'] = $rules;
            } else {
                $group['title'] = $param['title'];
                $group['description'] = $param['description'];
//                $group['status'] = $param['status'];
                $group['admin_login'] = $param['admin_login'];
//                $group['login_error_times'] = $param['login_error_times'];
//				$group['send_message'] = $param['send_message'];
//				$group['message_type'] = $param['message_type'];
//                $group['level'] = $param['level'];
//				$group['white_ip'] = $param['white_ip'];
//				$group['black_ip'] = $param['black_ip'];
            }
            $group->save();
            $data['data'] = $group;
            $data['code'] = 0;
        } catch (Exception $e) {
            $data['code'] = 1;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 新增|更新用户组
     * @param array $param
     * @param UserModel $user
     * @return mixed
     */
    public function update($param, $user = null)
    {
        try {
            if (!empty($param['id'])) {
                $group = AuthGroupModel::find($param['id']);
            } else {
                $group = new AuthGroupModel();
            }
            if (!UserEvent::isAdministrator($this->user)) {
                $role = $user->roles()->find();
                if ($role['level'] < $param['level']) {
                    throw new Exception('提升等级不足');
                }
                if (!empty($param['id'])) {
                    if ($role['level'] < $group['level']) {
                        throw new Exception('权限等级不足');
                    }
                }
            }
            //                $group['type'] = $param['type'];
            $group['title'] = $param['title'];
            $group['description'] = $param['description'];
            //            $group['experience'] = $param['experience'];
            if (!$group->save()) {
                throw new Exception('数据储存失败');
            }
            $data['data'] = $group;
            $data['code'] = 0;
        } catch (Exception $e) {
            $data['code'] = 1;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

}
